#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<cassert>

#include<sys/types.h>
#include<sys/wait.h>

#include<cstring>
#include<string>


using namespace std;

int main()
{
    //第一步，创建管道文件，打开读写端
    //std::cout<<"hello C++"<<std::endl;
    int fds[2];
    int n = pipe(fds);
    assert(n == 0);

    //cout<<"fds[0]:"<<fds[0]<<endl;
    //cout<<"fds[1]:"<<fds[1]<<endl;
    //3和4谁是读，谁是写
    //[0]读取,嘴巴，用来读
    //[1]写入，笔，用来写



    //第二步，父进程fork创建子进程
    pid_t id = fork();
    assert(id >= 0);
    if(id == 0)
    {
        //子进程通信代码
        close(fds[0]);

        //string msg = "hello ,I am child";
        const char* s = "我是子进程，我正在给你发消息";
        int cnt = 0;
        while(true)
        {
            cnt++;
            char buffer[1024];
            snprintf(buffer,sizeof buffer,"child->parent say: %s[%d] [%d]",s,cnt,getpid());
            write(fds[1],buffer,strlen(buffer));
            //sleep(1);//细节，每隔1s写一次
            break;
        }

        //子进程
        close(fds[1]);
        //sleep(100000);
        exit(0);
    }


    close(fds[1]);

    while(true)
    {
        sleep(2);
        char buffer[1024];
        //read是一种阻塞式读取，读不到就阻塞等待，除非子进程退出或者结束写数据
        ssize_t s = read(fds[0],buffer,sizeof (buffer) -1);
        if(s > 0)
        {
            buffer[s] = 0;
            cout << "get message# "<< buffer <<" | my pid:" <<getpid() <<endl;
        }
        else if(s == 0)
        {
            cout<<"s = "<< s <<endl;
            break;
        }
        //cout << "get message# "<< buffer <<" | my pid:" <<getpid() <<endl;
        //sleep(2);
    }


    //父进程通信代码
    n = waitpid(id,nullptr,0);
    assert(n == id);
    close(fds[0]);



    return 0;
}




